package com.xxh.dasongapp.security.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.xxh.dasongapp.common.Result;
import com.xxh.dasongapp.common.ResultCode;
import com.xxh.dasongapp.common.entity.User;
import com.xxh.dasongapp.security.common.entity.*;
import com.xxh.dasongapp.security.common.param.LoginPARAM;
import com.xxh.dasongapp.security.common.param.WxLoginPARAM;
import com.xxh.dasongapp.security.config.WxAppletAuthenticationToken;
import com.xxh.dasongapp.security.service.LoginService;
import com.xxh.dasongapp.security.utils.JwtUtil;
import com.xxh.dasongapp.security.utils.WechatUtil;
import com.xxh.dasongapp.service.UserService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.List;

@Service
@Log4j2
public class LoginServiceImpl implements LoginService {
    @Autowired
    @Qualifier("userNameDetailServiceImpl")
    UserDetailsService userDetailsService;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    @Qualifier("myAuthenticationManager")
    AuthenticationManager authenticationManager;

    @Autowired
    UserService userService;



    @Override
    public Result login(LoginPARAM loginPARAM) {

        UserDetails userDetails = userDetailsService.loadUserByUsername(loginPARAM.getUsername());
        if(userDetails == null){
            return Result.error(ResultCode.BAD_REQUEST.getCode(),"用户名或密码错误");
        }
        //对比密码
        if(!passwordEncoder.matches(loginPARAM.getPassword(),userDetails.getPassword())){
            return Result.error(ResultCode.BAD_REQUEST.getCode(),"用户名或密码错误");
       }
        //选则security带的token（继承Authentication）需要赋值用户名密码
        //选用不同的token，会通过循环找到token对应的provider，利用provider进行验证
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
                new UsernamePasswordAuthenticationToken(loginPARAM.getUsername(),loginPARAM.getPassword());
        String token = this.authenticate(usernamePasswordAuthenticationToken);

        HashMap<String, Object> map = new HashMap<>();
        map.put("token",token);
        map.put("user",userService.getUserAndRoleByUsername(loginPARAM.getUsername()));

        return Result.success("登录成功",map);
    }

    @Override
    public Result wxlogin(WxLoginPARAM wxLoginPARAM) {

        // 1.接收小程序发送的code
        // 2.开发者服务器 登录凭证校验接口 appi + appsecret + code
        JSONObject SessionKeyOpenId = WechatUtil.getSessionKeyOrOpenId(wxLoginPARAM.getCode());
        String openId = SessionKeyOpenId.getString("openid");
        String sessionKey = SessionKeyOpenId.getString("session_key");
        // 4.校验签名 小程序发送的签名signature与服务器端生成的签名signature2 = sha1(rawData + sessionKey)
        String signature2 = DigestUtils.sha1Hex(wxLoginPARAM.getRawData() + sessionKey);
//        if (!wxLoginPARAM.getSignature().equals(signature2)) {
//            return Result.error("signature error");
//        }
        User user =userService.getByOpenId(openId);

        if(user==null){
            //todo 插入数据
            User newUser = new User();
            newUser.setOpenId(openId);
            newUser.setStatus(1);
            userService.saveUserAndRole(newUser,2);
        }

        WxAppletAuthenticationToken wxAuthenticationToken = new WxAppletAuthenticationToken(openId);
        String token = this.authenticate(wxAuthenticationToken);

        return Result.success(ResultCode.SUCCESS.getCode(),token);
    }


    /**
     * AuthenticationManager调用proverManager去寻找合适的验证方式去选择不同的proverder
     * return token
     */
    private String authenticate(Authentication authentication){
        Authentication authenticate = authenticationManager.authenticate(authentication);
        //认证通过，使用userID生成token，再将token返回前端
        LoginUser loginUser = (LoginUser)authenticate.getPrincipal();
        User user = loginUser.getUser();
        //若果认证没通过给出提示
        if(user == null){
            throw new RuntimeException("登录失败");
        }


        List<String> permissions = loginUser.getPermissions();
        if (!permissions.isEmpty()){
            String role = permissions.get(0);
            String token = JwtUtil.createToken(user.getUsername(),role,user.getOpenId());
            return token;
        } else{
            Assert.isTrue(true,"服务器权限异常");
            log.error("用户权限关联出错");
            String token = JwtUtil.createToken(null,null,null);
            return token;
        }



    }


}
